package com.zrrd.gmall.product.service.impl;

import com.zrrd.gmall.product.service.TestService;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;


@Service
public   class TestServiceImpl implements TestService {
    @Autowired
    private StringRedisTemplate redisTemplate;
    //引入redisson解决
    @Autowired
    private RedissonClient redissonClient;
    @Override
    public  void testLock() throws InterruptedException {
        //解决缓存击穿，由于分布式锁存在许多难以解决的问题，所以引入一个redisson来解决问题，它的底层还是redis，所以我们不用写了
        //只需创建锁，上锁，业务，解锁 加入redssion后不需要本地锁了去掉
        String skuId="45";
        String lockKey="lock"+skuId;
        RLock lock = redissonClient.getLock(lockKey);
        //上锁 可重入锁
        boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
        if (res) {
            try {
                //查询redis中key为num的值
                String value = redisTemplate.opsForValue().get("num");
                if (StringUtils.isBlank(value)) {
                    return;
                }
                //将value变成整数
                int num = Integer.parseInt(value);
                //将num+1重新加入redis中
                redisTemplate.opsForValue().set("num", String.valueOf(++num));
            }catch (Exception e){
                System.out.println("业务异常：信息是==》"+e.getMessage());
            }finally {
                //无论发生什么都要解锁
                lock.unlock();
            }

        }

    }

    @Override
    public String readLock() throws InterruptedException {
        //初始化读写锁
        RReadWriteLock readwriteLock = redissonClient.getReadWriteLock("readwriteLock");
        RLock rLock = readwriteLock.readLock();
        //设置自动解锁
        rLock.tryLock(10,TimeUnit.SECONDS);
        //读取指定的内容
        String msg = redisTemplate.opsForValue().get("msg");
        return msg;
    }

    @Override
    public String writeLock() {
        //初始化读写锁
        RReadWriteLock readwriteLock = redissonClient.getReadWriteLock("readwriteLock");
        RLock writeLock = readwriteLock.writeLock();
        //设置自动解锁
        writeLock.lock(10,TimeUnit.SECONDS);
        //写入
        String uuid = UUID.randomUUID().toString();
        redisTemplate.opsForValue().set("msg",uuid);
        return "写入数据"+uuid;
    }
}
